﻿using System;
using System.Collections.Generic;
using System.Windows.Forms;

namespace Microsoft.WowAddonStudio.TocEditor
{
	/// <summary>
	/// The control that is presented on the file sheet of the TOC editor.
	/// </summary>
	public partial class FileListSelectorControl : UserControl
	{
		private readonly IFileListManager manager;

		/// <summary>
		/// Initializes a new instance of the <see cref="FileListSelectorControl"/> class.
		/// </summary>
		/// <param name="manager">The manager.</param>
		public FileListSelectorControl(IFileListManager manager)
		{
			if (manager == null)
				throw new ArgumentNullException("manager");

			InitializeComponent();

			this.manager = manager;
			RebindList(manager.Files);
			this.manager.OnFileListChanged += manager_OnFileListChanged;

			upButton.Enabled = false;
			downButton.Enabled = false;
			fileList.ColumnWidth = fileList.Width/2;
		}

		/// <summary>
		/// Handles the OnFileListChanged event of the manager control.
		/// </summary>
		/// <param name="sender">The source of the event.</param>
		/// <param name="e">The <see cref="Microsoft.WowAddonStudio.TocEditor.FileListManagerEventArgs"/> instance containing the event data.</param>
		private void manager_OnFileListChanged(object sender, FileListManagerEventArgs e)
		{
			RebindList(e.FileList);
			if (e.SelectedIndex >= 0)
				fileList.SelectedIndex = e.SelectedIndex;
		}

		/// <summary>
		/// Rebinds the list.
		/// </summary>
		/// <param name="files">The files.</param>
		private void RebindList(IEnumerable<IFileRepresentation> files)
		{
			UnsubscribeFromEvents();
			fileList.Items.Clear();
			foreach (var fileRepresentation in files)
			{
				fileList.Items.Add(fileRepresentation, fileRepresentation.IsIncluded);
			}

			SubscribeToEvents();
		}

		/// <summary>
		/// Subscribes to events.
		/// </summary>
		private void SubscribeToEvents()
		{
			upButton.Click += upButton_Click;
			downButton.Click += downButton_Click;
			fileList.SelectedIndexChanged += fileList_SelectedIndexChanged;
			fileList.ItemCheck += fileList_ItemCheck;
		}

		/// <summary>
		/// Unsubscribes from events.
		/// </summary>
		private void UnsubscribeFromEvents()
		{
			upButton.Click -= upButton_Click;
			downButton.Click -= downButton_Click;
			fileList.SelectedIndexChanged -= fileList_SelectedIndexChanged;
			fileList.ItemCheck -= fileList_ItemCheck;
		}

		/// <summary>
		/// Handles the SelectedIndexChanged event of the fileList control.
		/// </summary>
		/// <param name="sender">The source of the event.</param>
		/// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
		private void fileList_SelectedIndexChanged(object sender, EventArgs e)
		{
			if (fileList.SelectedIndex > -1)
			{
				upButton.Enabled = fileList.SelectedIndex > 0;

				downButton.Enabled = fileList.SelectedIndex < fileList.Items.Count - 1;
			}
		}

		/// <summary>
		/// Handles the Click event of the upButton control.
		/// </summary>
		/// <param name="sender">The source of the event.</param>
		/// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
		private void upButton_Click(object sender, EventArgs e)
		{
			manager.MoveUp(fileList.SelectedItem as IFileRepresentation);
		}

		/// <summary>
		/// Handles the Click event of the downButton control.
		/// </summary>
		/// <param name="sender">The source of the event.</param>
		/// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
		private void downButton_Click(object sender, EventArgs e)
		{
			manager.MoveDown(fileList.SelectedItem as IFileRepresentation);
		}

		/// <summary>
		/// Handles the ItemCheck event of the fileList control.
		/// </summary>
		/// <param name="sender">The source of the event.</param>
		/// <param name="e">The <see cref="System.Windows.Forms.ItemCheckEventArgs"/> instance containing the event data.</param>
		private void fileList_ItemCheck(object sender, ItemCheckEventArgs e)
		{
			manager.ChangeIncludeState(fileList.Items[e.Index] as IFileRepresentation);
		}
	}
}